package noema.processManagement;

import java.util.HashMap;
import java.util.Map;

import javax.ejb.Stateless;
import javax.ejb.EJB;
import javax.interceptor.Interceptors;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import noema.dataModel.Patient;
import noema.dataModel.LongEntity;
import noema.interceptor.LoggerInterceptor;
import noema.session.SessionFactory;

import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.process.ProcessInstance;

@Interceptors({ LoggerInterceptor.class })
@Stateless
public class ProcessManagementImpl implements ProcessManagement {

	private final String HOSPITALIZATION_PROCESS_ID = "dummyHospitalization";
	@EJB
	private SessionFactory sessionFactory;
	@PersistenceContext(unitName = "application.data")
	private EntityManager em;

	@Override
	public Patient startHospitalization(String healthCardId, String name,
			String surname) {
		Patient p = em.find(Patient.class, healthCardId);
		StatefulKnowledgeSession ksession = null;
		try {
			if (p == null) {
				p = new Patient(healthCardId, name, surname);
				ksession = sessionFactory.getNewSession();
				p.setSessionId(ksession.getId());
				em.persist(p);				
			} else {
				ksession = sessionFactory.getSession(p);
			}
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("patient", p);
			
			ProcessInstance instance = ksession.startProcess(
					HOSPITALIZATION_PROCESS_ID, params);
			p.getProcessIds().add(new LongEntity(instance.getId()));
			return p;
		} finally {
			if (ksession != null) {
				ksession.dispose();
			}
		}
	}

	@Override
	public void startPathWay(Patient p, String pathwayId) {
		StatefulKnowledgeSession ksession = sessionFactory.getSession(p);
		try {
			for (ProcessInstance instance : ksession.getProcessInstances()) {
				if (instance.getProcessId().equals(pathwayId)) {
					throw new IllegalArgumentException("There is already a "
							+ pathwayId + " active for " + p);
				}
			}
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("patient", p);
			ProcessInstance instance = ksession.startProcess(pathwayId, params);
			p.getProcessIds().add(new LongEntity(instance.getId()));
		} finally {
			ksession.dispose();
		}
	}

	@Override
	public void abortHospitalization(Patient p) {
		StatefulKnowledgeSession ksession = sessionFactory.getSession(p);
		try {
			p = em.find(Patient.class, p.getHealthCardId());
			if (p != null) {
				for (ProcessInstance instance : ksession.getProcessInstances()) {
					ksession.abortProcessInstance(instance.getId());
				}
				p.getProcessIds().clear();
			}
		} finally {
			ksession.dispose();
		}
	}

	@Override
	public void abortPathway(Patient p, String pathwayId) {
		StatefulKnowledgeSession ksession = sessionFactory.getSession(p);
		try {
			p = em.find(Patient.class, p.getHealthCardId());
			if (p != null) {
				for (ProcessInstance instance : ksession.getProcessInstances()) {
					if (instance.getProcessId().equals(pathwayId)) {
						ksession.abortProcessInstance(instance.getId());
						p.getProcessIds().remove(new Long(instance.getId()));
						break;
					}
				}
			}
		} finally {
			ksession.dispose();
		}
	}
}
